<template>
  <div class="intelligent-qa-panel">
    <!-- 头部区域 -->
    <div class="header">
      <img :src="refreshIconBase64" alt="Logo" class="logo" />
      <h1>徐工数据清洗助手</h1>
    </div>
    <!-- 欢迎词 -->
    <p class="welcome-message">您好！欢迎使用徐工数据清洗助手.</p>
    <!-- 问题和回答展示区域 -->
    <div class="conversation-display">
      <transition-group name="fade">
        <!-- 显示用户问题和对应的回答 -->
        <div v-for="(item, index) in conversation" :key="index">
          <!-- 用户问题 -->
          <div
            class="message user"
            v-if="item.content || item.fileInfo.hasFileName"
          >
            <div class="user-span">
              <img src="../assets/user.svg" alt="Avatar" class="imag imags" />
            </div>
            <div class="message-content">
              <!-- 显示文件名的区域 -->
              <div class="file" v-if="item.fileInfo.hasFileName">
                <a
                  class="file-name-display"
                  :href="fileUrl"
                  download="{{ item.fileInfo.fileName }}"
                  target="_blank"
                >
                  {{ item.fileInfo.fileName }}
                </a>
              </div>
              <div v-html="item.content"></div>
            </div>
          </div>
          <!-- AI 回答结果 -->
          <div v-if="item.answer" class="message ai">
            <img :src="refreshIconBase64" alt="Avatar" class="avatar" />
            <div class="message-content">
              <p v-if="item.answer.length > 0" v-html="item.answer"></p>
              <!-- 如果还未获取答案，显示搜索提示 -->
            </div>
          </div>
          <div v-if="item.answer.length === 0" class="searching-indicator">
            正在联网搜索答案...
          </div>
        </div>
      </transition-group>
    </div>
    <!-- 提问区域 -->
    <div class="question-input-wrapper">
      <!-- 根据请求状态显示停止生成按钮 -->
      <a-button
        v-if="isRequesting"
        class="stop-generation"
        @click="stopGeneration"
      >
        <div class="stop-generation-btn">
          <img src="../assets/stop.svg" alt="" class="imag" />
          <span class="imag-margin"> 停止生成</span>
        </div>
      </a-button>
      <div class="question">
        <div class="clear" @click="clearConversation">
          <img src="../assets/clear.svg" alt="Avatar" class="imag imags" />
        </div>
        <div class="question-input-area custom-textarea-container">
          <div class="textarea">
            <!-- 显示文件名的区域 -->
            <div class="file">
              <a
                v-if="hasFileName"
                class="file-name-display"
                :href="fileUrl"
                download="{{ fileName }}"
                target="_blank"
              >
                {{ fileName }}
              </a>
            </div>

            <a-textarea
              v-model:value="userQuestion"
              @input="logInputValue"
              @keydown="handleKeyDown"
              style="resize: none"
              placeholder="请在此处输入对话，Enter键发送问题，Ctrl+Enter键换行"
            ></a-textarea>
          </div>

          <div class="inside-right-container">
            <!-- 上传图标，点击触发文件选择 -->
            <img
              src="../assets/link.svg"
              alt="Upload"
              class="imag"
              @click="triggerFileInput"
            />
            <!-- 隐藏的文件输入框 -->
            <input
              ref="fileInput"
              type="file"
              style="display: none"
              accept=".csv,.xlsx,.xls,.txt"
              @change="handleFileChange"
            />
            <img
              src="@/assets/images/send.png"
              class="imag"
              @click="sendQuestion"
            />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref } from "vue";
import { refreshIconBase64 } from "./base64Icons";
import { v4 as uuidv4 } from "uuid";
import { marked } from "marked";
import { uploadAPI } from "@/apis";
// 定义响应式数据
const userQuestion = ref("");
const fileName = ref("");
const ansFileName = ref("");
const hasFileName = ref(false);
const fileInput = ref(null);
const fileUrl = ref(""); // 新增响应式变量
const pathUrl = ref("");
let Token = "";
const updloadFile = async (file) => {
  const formData = new FormData();
  formData.append("file", file, file.name);
  const res = await uploadAPI(formData);
  pathUrl.value = res.path;
};
// 处理文件选择事件
const handleFileChange = (event) => {
  const file = event.target.files[0];
  if (file) {
    fileName.value = file.name;
    hasFileName.value = true;
    fileUrl.value = URL.createObjectURL(file); // 设置文件的临时 URL
    updloadFile(file);
  }
  // 清空文件输入框，以便下次选择相同文件也能触发事件
  event.target.value = "";
};

// 触发文件选择对话框
const triggerFileInput = () => {
  if (fileInput.value) {
    fileInput.value.click();
  }
};
const aiIcon = "path/to/ai-icon.png"; // 替换为实际的 AI 图标路径
const userIcon = "path/to/user-icon.png"; // 替换为实际的用户图标路径
const conversation = ref([
  {
    id: uuidv4(),
    content: "",
    answer:
      "欢迎使用徐工数据治理AI应用！我们致力于为您提供高效的数据治理AI服务，让您体验更便捷、更高效的数据治理工作方式。together开启AI之旅吧！",
    fileInfo: {
      fileName: "",
      fileUrl: "",
      hasFileName: false,
    },
  },
]);
// 跟踪请求是否正在进行
const isRequesting = ref(false);
// 用于中断请求的控制器
let abortController = null;

const clearConversation = () => {
  firstSend = false;
  userQuestion.value = "";
  conversation.value = [
    {
      id: uuidv4(),
      content: "",
      answer:
        "欢迎使用徐工数据治理AI应用！我们致力于为您提供高效的数据治理AI服务，让您体验更便捷、更高效的数据治理工作方式。together开启AI之旅吧！",
      fileInfo: {
        fileName: "",
        fileUrl: "",
        hasFileName: false,
      },
    },
  ];
  // 清空文件相关信息
  fileName.value = "";
  hasFileName.value = false;
  fileUrl.value = "";
  pathUrl.value = "";
  if (fileInput.value) {
    fileInput.value.value = ""; // 清空文件输入框
  }
};
const markdownToHtml = (md) => {
  return marked.parse(md);
};
let firstSend = false;
// 发送问题
const sendQuestion = async () => {
  if (userQuestion.value.trim() || hasFileName.value) {
    const questionId = uuidv4();
    const newItem = {
      id: questionId,
      content: userQuestion.value,
      answer: "",
      fileInfo: {
        fileName: fileName.value,
        fileUrl: fileUrl.value,
        hasFileName: !!fileName.value,
      },
    };
    let userQuestions = userQuestion.value;
    // 清空输入框
    userQuestion.value = "";
    // 清空文件相关信息
    fileName.value = "";
    // 直接添加新的问题项，覆盖默认回答
    if (!firstSend) conversation.value = [];
    firstSend = true;
    conversation.value.push(newItem);
    // 创建新的 AbortController
    abortController = new AbortController();
    const signal = abortController.signal;
    try {
      // 标记请求开始
      isRequesting.value = true;
      // 创建 FormData 对象
      const formData = new FormData();
      formData.append("question", userQuestion.value);
      if (hasFileName.value) {
        const fileInputElement = fileInput.value;
        if (fileInputElement && fileInputElement.files[0]) {
          const file = fileInputElement.files[0];
          formData.append("file", file, file.name);
        }
      }
      await fetchAnswer(userQuestions, questionId, signal); // 处理问题
    } catch (error) {
      if (error.name === "AbortError") {
        const targetItem = conversation.value.find(
          (item) => item.id === questionId
        );
        if (targetItem) {
          targetItem.answer = "请求已被用户取消。";
        }
      } else {
        console.error("获取答案时出错:", error);
        const targetItem = conversation.value.find(
          (item) => item.id === questionId
        );
        if (targetItem) {
          targetItem.answer = "抱歉，获取答案时出错，请稍后再试。";
        }
      }
    } finally {
      // 标记请求结束
      isRequesting.value = false;
    }

    hasFileName.value = false;
    fileUrl.value = "";
  }
};

const getToken = async () => {
  const resp = await fetch("http://1.95.83.155/api/request_token", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({}),
  });
  const res = await resp.json();
  Token = res.token;
};

const answerRes = async (uid) => {
  try {
    // 构造请求 URL（假设是 GET 请求，参数拼接到 URL 中）
    const url = `/api/v1/f3f334ee2d214cb8abfcaadea3a13204/agents/af15e7d6-e970-4a2e-9e7f-19b04a52681c/conversations/${uid}`;
    // 发起请求
    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-Auth-Token": Token,
      },
      body: JSON.stringify({
        query: `${userQuestion.value}${pathUrl.value}`,
      }),
    });

    // 检查响应状态
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    // 解析响应数据
    const data = await response.json();
    console.log("API response:", data);
    return data;
  } catch (error) {
    console.error("Error fetching data:", error);
    throw error; // 抛出错误以便调用者处理
  }
};
// 模拟调用 AI 接口获取回答，需替换为实际接口
const fetchAnswer = async (userQuestions, questionId, signal) => {
  const response = await fetch(
    `/api/v1/f3f334ee2d214cb8abfcaadea3a13204/agents/af15e7d6-e970-4a2e-9e7f-19b04a52681c/conversations/${uuidv4()}`,
    {
      method: "POST",
      signal,
      body: JSON.stringify({ query: userQuestions + pathUrl.value }),
      headers: {
        "Content-Type": "application/json",
        "X-Auth-Token": Token,
      },
    }
  );

  const reader = await response.body.getReader();
  const decoder = new TextDecoder();
  let partialLine = ""; // 用于存储不完整的行
  let count = 0;
  while (count < 200) {
    count++;
    const { done, value } = await reader.read();
    if (value) {
      const chunk = decoder.decode(value, { stream: true });
      const lines = (partialLine + chunk).split("\n");
      partialLine = lines.pop() || ""; // 最后一行可能不完整，保存到下一次处理
      for (const line of lines) {
        const trimmedLine = line.trim();
        if (trimmedLine.startsWith("data:")) {
          const jsonPart = trimmedLine.slice("data:".length).trim();
          try {
            const jsonData = JSON.parse(jsonPart);
            const targetItem = conversation.value.find(
              (item) => item.id === questionId
            );
            // 检查解析后的数据是否有 content 字段
            if (
              targetItem &&
              jsonData.hasOwnProperty("content") &&
              jsonData.event == "summary_response"
            ) {
              targetItem.answer += markdownToHtml(jsonData.content);
            }
            if (jsonData.event == "done") {
              break;
            }
            console.log("解析后的 JSON 数据:", jsonData, conversation.value);
          } catch (parseError) {
            console.error("解析 JSON 时出错:", parseError);
          }
        }
      }
    }
    // if (done) {
    //   // 处理最后可能剩余的部分
    //   if (partialLine.trim().startsWith("data:")) {
    //     const jsonPart = partialLine.trim().slice("data:".length).trim();
    //     try {
    //       const jsonData = JSON.parse(jsonPart);
    //       const targetItem = conversation.value.find(
    //         (item) => item.id === questionId
    //       );
    //       // 检查解析后的数据是否有 content 字段
    //       if (targetItem && jsonData.hasOwnProperty("content")) {
    //         targetItem.answer += jsonData.content;
    //       }
    //       console.log("解析后的 JSON 数据:", jsonData, conversation.value);
    //     } catch (parseError) {
    //       console.error("解析最后部分 JSON 时出错:", parseError);
    //     }
    //   }
    //   break;
    // }
  }

  if (!response.ok) {
    throw new Error("Network response was not ok");
  }
  // 由于是流式响应，可能不需要返回整个响应的 JSON
  // 这里可以根据实际需求返回合适的数据
  return "";
};

// 停止生成
const stopGeneration = () => {
  if (abortController) {
    // 中断请求
    abortController.abort();
    // 重置控制器
    abortController = null;
  }
};

// 刷新回答
const refreshAnswer = async () => {
  if (userQuestion.value.trim()) {
    const answer = await fetchAnswer(userQuestion.value);
    // 这里可以根据需求更新对话列表中的回答
  }
};

// 复制回答
const copyAnswer = () => {
  if (conversation.value.length > 0) {
    const lastAnswer = conversation.value.findLast((item) => item.answer);
    if (lastAnswer) {
      navigator.clipboard.writeText(lastAnswer.answer);
    }
  }
};

// 上传前的钩子函数，阻止自动上传
const beforeUpload = () => {
  return false;
};

// 处理上传文件变化
const handleUploadChange = ({ file }) => {
  if (file.status === "done") {
    console.log("文件上传成功");
    // 可以在这里添加文件处理逻辑
  } else if (file.status === "error") {
    console.log("文件上传失败");
  }
  // 模拟原有的文件选择逻辑
  if (file.originFileObj) {
    fileName.value = file.name;
    hasFileName.value = true;
  }
};

// 处理键盘按下事件
const handleKeyDown = (event) => {
  if (event.key === "Enter") {
    if (event.ctrlKey) {
      // Ctrl + Enter 组合键，插入换行符
      event.preventDefault(); // 阻止默认的换行行为
      insertNewLine();
    } else {
      // 单独按下 Enter 键，发送问题
      event.preventDefault(); // 阻止默认的换行行为
      sendQuestion();
    }
  }
};

// 在输入框中插入换行符
const insertNewLine = () => {
  userQuestion.value += "\n";
};

// 添加输入日志函数
const logInputValue = () => {
  console.log("输入框当前值:", userQuestion.value);
};
onMounted(async () => {
  await getToken();
  marked.setOptions({
    breaks: true, // 换行符转换为 <br>
  });
});
</script>

<style scoped>
/* 去掉 body 的外边距和内边距，并隐藏滚动条 */
body {
  margin: 0;
  padding: 0;
  overflow: hidden;
}
.imag {
  width: 24px !important;
  height: 24px !important;
  cursor: pointer;
}
.imag-margin {
  margin-left: 8px;
}
.intelligent-qa-panel {
  padding: 20px;
  height: 100%;
  position: relative;
  overflow: hidden;
  width: 60%;
}

.header {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 32px;
}

.logo {
  height: 60px;
  margin-right: 16px;
}

h1 {
  font-size: 40px;
  font-weight: bold;
  margin: 0;
}

/* 修改欢迎词样式，使其文本居中 */
.welcome-message {
  margin-bottom: 32px;
  text-align: center;
}

.conversation-display {
  border-radius: 20px;
  padding: 20px;
  position: absolute;
  top: 150px;
  left: 20px;
  right: 20px;
  max-height: calc(100vh - 385px);
  overflow-y: auto;
  scrollbar-width: none;
}

.message {
  display: flex;
  margin-bottom: 15px;
  animation: fadeIn 0.5s ease-in-out;
  border-radius: 20px;
}

.avatar {
  width: 32px;
  height: 32px;
  margin-top: 10px;
  border-radius: 50%;
  margin-right: 10px;
}

.message-content {
  padding: 10px;
  border-radius: 10px;
}
.message-content div {
  color: #333;
}

/* 修改 message 样式，区分用户问题和 AI 回答 */
.message.user {
  padding: 10px;
  justify-content: flex-start; /* 用户问题靠左 */
  background-color: #e2e5ee; /* 用户问题背景色 */
}
.user-span {
  background-color: #fff;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  margin-top: 5px;
}
.message.ai {
  padding: 10px;
  background-color: #fff; /* AI 回答背景色 */
}

.message.user .message-content {
  color: white;
}

.message.ai .message-content {
  color: #333;
}
.searching-indicator {
  font-size: 12px;
  color: #666;
  margin-top: 5px;
}
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
.answer-display > p {
  display: inline-block;
  width: calc(100% - 60px);
}

.answer-actions {
  position: absolute;
  bottom: 10px;
  right: 10px;
}

.question-input-wrapper {
  position: absolute;
  bottom: 20px;
  left: 20px;
  right: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* 隐藏 a-textarea 的边框 */
  .ant-input-textarea textarea {
    border: none;
    box-shadow: none;
    /* 移除聚焦时的默认边框 */
    outline: none;
  }
}
/* 隐藏 a-textarea 的边框 */
:deep(.ant-input) {
  border: none;
  box-shadow: none;
  /* 移除聚焦时的默认边框 */
  outline: none;
}

.question-input-area {
  display: flex;
  gap: 10px;
  width: 100%;
}

.ant-input-textarea {
  position: relative;
}

.textarea-icons {
  position: absolute;
  right: 20px; /* 图标距离右侧 20px */
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  gap: 10px;
}

/* 隐藏 a-textarea 的边框 */
.ant-input-textarea textarea {
  border: none;
  box-shadow: none;
  outline: none;
  /* 可以在这里设置默认文字样式 */
  color: #333;
  font-size: 14px;
}

/* 鼠标悬停时，文字和边框样式保持不变 */
.ant-input-textarea textarea:hover {
  border: none;
  box-shadow: none;
  outline: none;
  /* 保持文字样式和默认状态一致 */
  color: #333;
  font-size: 14px;
}
.custom-btn {
  border: none;
  box-shadow: none;
  /* 移除聚焦时的默认边框 */
  outline: none;
}

/* 移除鼠标悬停和激活状态下的边框 */
.custom-btn:hover,
.custom-btn:active {
  border: none;
  box-shadow: none;
}

/* 给最外层 div 添加边框 */
.custom-textarea-container {
  width: calc(100% - 40px); /* 减去图标宽度 */
  background-color: #fff !important;
  border: 1px solid #d9d9d9; /* 默认的 Ant Design 边框颜色 */
  border-radius: 20px; /* 与 Ant Design 默认的边框圆角一致 */
  padding: 4px 11px; /* 与 Ant Design 默认的内边距一致 */
}

/* 鼠标悬停和聚焦时的边框样式 */
.custom-textarea-container:hover {
  border-color: #40a9ff;
}

.custom-textarea-container:focus-within {
  border-color: #40a9ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
.inside-right-container {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  flex-wrap: nowrap; /* 防止元素换行 */
}
.stop-generation {
  margin-bottom: 10px;
  height: 40px;
}
.stop-generation-btn {
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
}
:deep(.ant-btn-default) {
  border: none;
  margin-left: 0 !important;
}
.question {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}
.clear {
  margin-right: 10px; /* 调整间距 */
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 62px; /* 调整宽度 */
  height: 62px; /* 调整高度 */
  border: #d9d9d9 1px solid;
  background-color: #fff;
}
.file-name-display {
  color: blue;
  margin-right: 10px; /* 添加右侧间距，让文件名和上传按钮有间隔 */
  max-width: 150px; /* 限制文件名最大宽度，避免过长影响布局 */
  overflow: hidden;
  text-overflow: ellipsis; /* 超出部分显示省略号 */
  white-space: nowrap;
}
.custom-file-input {
  display: none;
}
.textarea {
  width: 100%;
  /* height: 100px; */
}
.file {
  width: 100%;
  min-height: 20px;
  padding: 4px 10px;
}
</style>
